import { fixedRules, randomRules, blackList } from "./formulaSheet.js";
import * as utils from "./synthesisUtils.js";

export class Game_SynthesisItem extends Game_Item {
  constructor(item) {
    super(item);
    this._meta = item.meta;
  }

  setObject(item) {
    if (
      DataManager.isItem(item) ||
      DataManager.isWeapon(item) ||
      DataManager.isArmor(item)
    ) {
      if (Imported.YEP_ItemCore) item = DataManager.getBaseItem(item);
      super.setObject(item);
    } else {
      super.setObject(null);
    }
  }

  object() {
    if (this.isSynthesisItem()) return super.object();

    return null;
  }

  isSynthesisItem() {
    return this.isItem() || this.isWeapon() || this.isArmor();
  }

  getSynthesisItemObject() {
    if (!this.isSynthesisItem()) return ["", 0];
    return [this._dataClass, this._itemId];
  }

  equals(obj) {
    if (!(obj instanceof Game_SynthesisItem)) return false;
    const o1 = this.getSynthesisItemObject();
    const o2 = obj.getSynthesisItemObject();

    return o1[0] === o2[0] && o1[1] === o2[1];
  }
}


export const isInBlackList = (itemTypeId, item) => {
  if (!item) return false
  const blackArr = blackList.map(rule => rule.split(":"))

  const enemyBlackList = blackArr.filter(([dataClass]) => dataClass === "enemy").map(rule => Number(rule[1]))
  const armorBlackList = blackArr.filter(([dataClass]) => dataClass === "armor").map(rule => Number(rule[1]))

  const enemyClass = utils.getMetaAttr(item.meta, "Enemy Class", {
    formatter: Number,
  });
  if (enemyBlackList.includes(enemyClass)) return true

  // 如果是护驾
  if (itemTypeId === 2) {
    let currentId = item.id;
    if(DataManager.isIndependent(item) && item.baseItemId)currentId = item.baseItemId
    if (armorBlackList.includes(currentId)) {
      return true
    }
  }

  return false
}

// 查询固定公式
export const queryFixedFormula = (leftItem, rightItem) => {
  const formula = fixedRules.find(([type1, type2]) => {
    const [type1Class, type1Id] = type1.split(":");
    const [type2Class, type2Id] = type2.split(":");

    return (
      (leftItem._dataClass === type1Class &&
        leftItem._itemId === Number(type1Id) &&
        rightItem._dataClass === type2Class &&
        rightItem._itemId === Number(type2Id)) ||
      (leftItem._dataClass === type2Class &&
        leftItem._itemId === Number(type2Id) &&
        rightItem._dataClass === type1Class &&
        rightItem._itemId === Number(type1Id))
    );
  });

  if (!formula) {
    return {
      isValidFormula: false,
      formulaType: "fixed",
      leftItem,
      rightItem,
      produce: null,
      failureProduce: utils.getFailureProduceByItems(leftItem, rightItem),
    };
  }

  const [, , output] = formula;
  const [outputClass, outputId] = output.split(":");

  return {
    isValidFormula: true,
    formulaType: "fixed",
    leftItem,
    rightItem,
    produce: utils.getThing(outputClass, Number(outputId)),
    failureProduce: utils.getFailureProduce("common"),
  };
};

// 查询随机公式
export const queryRandomFormula = (leftItem, rightItem) => {
  const formula = randomRules.find(([input1, input2]) => {
    const [input1Type, input1Value] = input1.split(":");
    const [input2Type, input2Value] = input2.split(":");

    const checkItem = (item, type, value) => {
      if (type === "enemy") {
        if (!item._meta || !item._meta["Enemy Id"]) return false;
        const enemy = utils.getEnemyByArmorEnemyId(item._meta["Enemy Id"]); // armor转enemy
        return enemy.meta["Enemy Class"].trim() === value;
      }

      if (type === "armor") {
        return item._dataClass === type && item._itemId === Number(value);
      }

      if (type === "qiwu") {
        return utils.isQiwu(item);
      }
      return false;
    };

    return (
      (checkItem(leftItem, input1Type, input1Value) &&
        checkItem(rightItem, input2Type, input2Value)) ||
      (checkItem(leftItem, input2Type, input2Value) &&
        checkItem(rightItem, input1Type, input1Value))
    );
  });

  if (!formula) {
    return {
      isValidFormula: false,
      formulaType: "random",
      failureType: "robot",
      leftItem,
      rightItem,
      produce: null,
      failureProduce: utils.getFailureProduceByItems(leftItem, rightItem),
    };
  }

  const [, , output] = formula;
  const [outputClass, outputId] = output.split(":");

  let produce = null;
  if (outputClass === "armor") {
    produce = utils.getThing("armor", Number(outputId)); // armor必然是确定的
  } else if (outputClass === "enemy") {
    const enemies = $dataEnemies.filter((enemy) => {
      if (!enemy || !enemy.meta || !enemy.meta["Enemy Class"]) return false;
      return enemy.meta["Enemy Class"].trim() === outputId;
    }).filter(enemy=>{
      const targetArmor = $dataArmors.find((armor) => {
        if (!armor || !armor.meta || !armor.meta["Enemy Id"]) return false;
        return Number(armor.meta["Enemy Id"].trim()) === enemy.id;
      })
      if(isInBlackList(2,targetArmor))return false; // 黑名单里排除
      return true;
    })
    const leftLevel = utils.getCatchLevelByItemMeta(leftItem._meta);
    const rightLevel = utils.getCatchLevelByItemMeta(rightItem._meta);
    const averageLevel = Math.floor((leftLevel + rightLevel) / 2);
    let closestEnemies = enemies
      .reduce((closest, enemy) => {
        const catchLevel = enemy.meta["Catch Level"]
          ? enemy.meta["Catch Level"]
          : "0";
        const enemyLevel = Number(catchLevel.trim());
        const levelDifference = Math.abs(enemyLevel - averageLevel);// 差值

        if (
          closest.length === 0 ||
          levelDifference < closest[0].levelDifference
        ) {
          return [{ enemy, levelDifference }];
        } else if (levelDifference === closest[0].levelDifference) {
          closest.push({ enemy, levelDifference });
        }

        return closest;
      }, [])
      .map((entry) => entry.enemy);
    closestEnemies = closestEnemies.filter(item => !isInBlackList('',item))

    const targetEnemy =
      closestEnemies[Math.floor(Math.random() * closestEnemies.length)];
    
    // 从dataArmors里找对应的eneyId，找到对应armorItem
    produce = $dataArmors.find((armor) => {
      if (!armor || !armor.meta || !armor.meta["Enemy Id"]) return false;
      return Number(armor.meta["Enemy Id"].trim()) === targetEnemy.id;
    }) || utils.getFailureProduceByItems(leftItem, rightItem);
  }

  return {
    isValidFormula: true,
    formulaType: "random",
    failureType: "common",
    leftItem,
    rightItem,
    produce,
    failureProduce: utils.getFailureProduceByItems(leftItem, rightItem),
  };
};

// 获得预计产物
export const getExpectedRecipe = (leftItem, rightItem) => {
  // 先检查固定配方
  const fixedResult = queryFixedFormula(leftItem, rightItem);
  if (fixedResult.isValidFormula) {
    return fixedResult;
  }

  // 再检查随机配方
  const randomResult = queryRandomFormula(leftItem, rightItem);
  if (randomResult.isValidFormula) {
    return randomResult;
  }

  // 如果都没有匹配的配方,返回null
  return {
    isValidFormula: false,
    formulaType: "null",
    failureType: "common",
    leftItem,
    rightItem,
    produce: utils.getFailureProduceByItems(leftItem, rightItem),
    failureProduce: utils.getFailureProduceByItems(leftItem, rightItem),
  };
};

// 实际生成产物过程
export const generateRecipe = (recipetInfo) => {
  const { isValidFormula, leftItem, rightItem, produce, failureProduce } =
    recipetInfo;

  const isSuccess = isValidFormula;
  const finalProduce = isSuccess ? produce : failureProduce;

  return {
    isSuccess, // 是否成功
    expectedProduce: produce, // 期望产物
    failureProduce, // 如果失败使用的产物
    finalProduce, // 实际最终产物
    leftItem: leftItem.object(),
    rightItem: rightItem.object(),
  };
};
